package com.attendance.www.hr.controller;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.attendance.www.hr.utils.UrlUtil;
import com.attendance.www.hr.beans.UserBean;
import com.attendance.www.hr.beans.UserEmployeeBean;
import com.attendance.www.hr.constant.AppConstant;
import com.attendance.www.hr.entitys.User;
import com.attendance.www.hr.exception.ResultFaultException;
import com.attendance.www.hr.service.IMenuService;
import com.attendance.www.hr.service.IUserService;
import com.attendance.www.hr.utils.CSRFTokenUtil;
import com.zhangkongli.frame.core.ResultMap;

import net.sf.json.JSONObject;

/**
 * 用户Controller
 * @version 2017/9/25
 * @author 崔棋
 *
 */
@Controller
@RequestMapping("/user")
public class UserController {
	
	@Resource
	private IUserService userService;
	@Resource
	private IMenuService menuService;
	
	/**
	 * 查询登陆用户数据
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getUserData.do", method = {RequestMethod.POST})
	@ResponseBody
	public Object getUserData(HttpServletRequest request){
		UserEmployeeBean userEmployee = (UserEmployeeBean)request.getSession().getAttribute(AppConstant.SESSIONUSER);
		if(userEmployee!=null){
			return ResultMap.success(userEmployee);
		}else{
			throw new ResultFaultException("1_00001");
		}
	}
	
	/**
	 * 初始化返回Session超时时间
	 * @param request
	 */
	@RequestMapping(value = "/getInitialized.do", method = {RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public Object getInitialized(HttpServletRequest request){
		return ResultMap.success(request.getSession().getMaxInactiveInterval());
	}
	
	
	/**
	 * 查询用户是否更改密码
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getVerificationPassword.do", method = {RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public Object getVerificationPassword(HttpServletRequest request){
		String loginName = request.getParameter("loginname");
		String passWord = request.getParameter("password");
		if(StringUtils.isNotBlank(loginName) && StringUtils.isNotBlank(passWord)){
			UserBean userBean=new UserBean();
			userBean.setUserName(loginName);
			userBean.setPassword(passWord);
			return ResultMap.success(userService.getVerificationPassword(userBean));
		}
		throw new ResultFaultException("0_00001");
	}
	
	
	/**
	 * 用户登录
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/login.do", method = {RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public Object login(HttpServletRequest request){
		//获取IP地址
		String ip = request.getHeader("x-forwarded-for"); 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("Proxy-Client-IP"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("WL-Proxy-Client-IP"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("HTTP_CLIENT_IP"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getRemoteAddr(); 
	    } 
		String loginName = request.getParameter("loginname");
		String passWord = request.getParameter("password");
		if(StringUtils.isNotBlank(loginName) && StringUtils.isNotBlank(passWord)){
		    /*UsernamePasswordToken token = new UsernamePasswordToken(loginName, passWord);  
	        token.setRememberMe(true);  
	        //System.out.println("为了验证登录用户而封装的token为" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));  
	        //获取当前的Subject  
	        Subject currentUser = SecurityUtils.getSubject();  
	        try {  
	            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查  
	            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应  
	            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法  
	            System.out.println("对用户[" + loginName + "]进行登录验证..验证开始");  
	            currentUser.login(token);  
	            System.out.println("对用户[" + loginName + "]进行登录验证..验证通过");  
	        }catch(UnknownAccountException uae){  
	            //System.out.println("对用户[" + loginName + "]进行登录验证..验证未通过,未知账户");  
	            //request.setAttribute("message_login", "账号不存在");  
	            throw new ResultFaultException("1_00002");
	        }catch(IncorrectCredentialsException ice){  
	            //System.out.println("对用户[" + loginName + "]进行登录验证..验证未通过,错误的凭证");  
	            //request.setAttribute("message_login", "密码不正确");  
	            throw new ResultFaultException("1_00003");
	        }catch(LockedAccountException lae){  
	            //System.out.println("对用户[" + loginName + "]进行登录验证..验证未通过,账户已锁定");  
	            //request.setAttribute("message_login", "帐号已被锁定");  
	            throw new ResultFaultException("1_00007");
	        }catch(ExcessiveAttemptsException eae){  
	            //System.out.println("对用户[" + loginName + "]进行登录验证..验证未通过,错误次数过多");  
	            //request.setAttribute("message_login", "用户名或密码错误次数过多");
	            throw new ResultFaultException("1_00008");
	        }catch(AuthenticationException ae){  
	            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
	            //System.out.println("对用户[" + loginName + "]进行登录验证..验证未通过,堆栈轨迹如下");  
	            ae.printStackTrace();  
	            //request.setAttribute("message_login", "用户名或密码不正确"); 
	            throw new ResultFaultException("1_00003");
	        }  
	        //验证是否登录成功  
	        if(currentUser.isAuthenticated()){  
	        	//参数未改变，无需重新登录，默认为已经登录成功  
	            System.out.println("用户[" + loginName + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");  
	        }else{  
	        	//需要重新登陆  
	            token.clear();  
	            throw new ResultFaultException("1_00001");
	        }  */
			UserBean userBean=new UserBean();
			userBean.setUserName(loginName);
			userBean.setPassword(passWord);
			Integer userId=userService.login(userBean);
			if(userId!=null){
				UserEmployeeBean userEmployee=userService.getUserEmployee(userId,ip);
				request.getSession().setMaxInactiveInterval(Math.round(AppConstant.SESSION_TIMEOUT));
				request.getSession().setAttribute(AppConstant.SESSIONUSER,userEmployee);
				return ResultMap.success(userEmployee);
			}
		}
		throw new ResultFaultException("0_00001");
	}	
	
	/**
	 * 用户注销
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/logout.do", method = {RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public Object logout(HttpServletRequest request){
		/*Subject subject = SecurityUtils.getSubject();  
	    if (subject != null) {  
	        try{  
	            subject.logout();  
	        }catch(Exception ex){  
	        }  
	    }  */
	    request.getSession().removeAttribute(AppConstant.SESSIONUSER);
		return ResultMap.success();
	}
	
	/**
	 * 修改密码
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/changepassword.do", method = {RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public Object changepassword(HttpServletRequest request){
		UserEmployeeBean userEmployee = (UserEmployeeBean)request.getSession().getAttribute(AppConstant.SESSIONUSER);
		String loginName =null;
		if(userEmployee==null){
			loginName= request.getParameter("loginName");
		}else{
			loginName = userEmployee.getUserName();
		}

		String oldPassWord = request.getParameter("oldPassword");
		String newPassWord = request.getParameter("newPassword");
		if(loginName!=null && oldPassWord!=null){
			UserBean userBean=new UserBean();
			userBean.setUserName(loginName);
			userBean.setPassword(oldPassWord);
			//验证旧密码是否正确
			User resultUser = userService.validateUser(userBean);
			if(resultUser!=null){
				//更新密码
				resultUser.setPassword(newPassWord);
				userService.updateUserPassWord(resultUser);
				return ResultMap.success();
			}
		}
		throw new ResultFaultException("2_00002");
	}
	
	/**
	 * 用户身份认证
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getCSRFToken.do", method = {RequestMethod.POST})
	@ResponseBody
	public Object getCSRFToken(HttpServletRequest request){
		String token=CSRFTokenUtil.generate();
		request.getSession().setMaxInactiveInterval(Math.round(AppConstant.SESSION_TIMEOUT));
		request.getSession().setAttribute("CSRFToken",token);
		return ResultMap.success(token);
	}
	
	/**
	 * 忘记密码
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/forgetPassword.do", method = {RequestMethod.POST})
	@ResponseBody
	public Object forgetPassword(HttpServletRequest request){
		String mail = request.getParameter("mail");
		if (StringUtils.isBlank(mail)) {
			throw new ResultFaultException("0_00001");
		}
		return ResultMap.success(userService.forgetPassword(mail));
	}
	
	/**
	 * Email重置密码
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/doResetPassword.do", method = {RequestMethod.POST,RequestMethod.GET})
	@ResponseBody
	public Object doResetPassword(HttpServletRequest request) {
		String newPasswd1 = request.getParameter("pw1");
		String newPasswd2 = request.getParameter("pw2");
		String key = request.getParameter("key");
		if (StringUtils.isBlank(newPasswd1) || StringUtils.isBlank(newPasswd1)|| StringUtils.isBlank(key)) {
			throw new ResultFaultException("0_00001");
		}
		if (!newPasswd1.equals(newPasswd2)) {
			throw new ResultFaultException("0_00035");
		}
		if (userService.doResetPassword(newPasswd1,key)) {
			return ResultMap.success(true);
		} else {
			return ResultMap.success(false);
		}
		
		// if equals update database.
		// else 
//		ModelAndView modelAndView = new ModelAndView();
//		modelAndView.setViewName("pw_reset");
//		modelAndView.addObject("errors", " password is error.");
//		return modelAndView;
	}
	
	/**
	 * 验证链接是否有效(key)
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/checkKey.do", method = {RequestMethod.GET, RequestMethod.POST})
	public Object checkKey(HttpServletRequest request) {
		String key = request.getParameter("key");
		
		Integer keyNum = userService.checkKey(key);
		if (keyNum!=null) {//有效key
			//获取IP地址
			String ip = request.getHeader("x-forwarded-for"); 
		    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		      ip = request.getHeader("Proxy-Client-IP"); 
		    } 
		    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		      ip = request.getHeader("WL-Proxy-Client-IP"); 
		    } 
		    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		      ip = request.getHeader("HTTP_CLIENT_IP"); 
		    } 
		    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		      ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
		    } 
		    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		      ip = request.getRemoteAddr(); 
		    }
		    Integer userId = userService.getUserId(key);
		    UserEmployeeBean userEmployee=userService.getUserEmployee(userId,ip);
		    if (keyNum!=0) {
		    	request.getSession().setMaxInactiveInterval(Math.round(AppConstant.SESSION_TIMEOUT));
		    	request.getSession().setAttribute(AppConstant.SESSIONUSER,userEmployee);
				return ResultMap.success(keyNum);
			}
			return ResultMap.success(keyNum);
		} else {
			return ResultMap.success(keyNum);
		}
	}
	
	/**
	 * 验证单点登录
	 * @param request
	 * @return
	 */
	@SuppressWarnings("static-access")
	@RequestMapping(value = "/getSingleSignOn.do", method = {RequestMethod.POST})
	@ResponseBody
	public Object getSingleSignOn(HttpServletRequest request){
		String bpmUrl=AppConstant.BPM_URL;
		String bpmAccessKey=AppConstant.BPM_ACCESS_KEY;
		//接收BPM传值TokenId，用于请求其他BPM接口时参数使用
		String tokenId=request.getParameter("tokenId");
		//请求BMP接口，获取登录员工信息
		String loginName = null;
		if(StringUtils.isBlank(bpmUrl)
				|| StringUtils.isBlank(bpmAccessKey)
				|| StringUtils.isBlank(tokenId)) {
			throw new ResultFaultException("1_00009");
		}
		
		//设置请求信息
		Map<String, String> param =new HashMap<>();
		param.put("cmd","com.actionsoft.apps.addons.sso_validate");	
		param.put("tokenId",tokenId);	
		param.put("access_key",bpmAccessKey);	
		String jsonData=UrlUtil.post(bpmUrl,param,"utf-8");
		if(jsonData==null) {
			throw new ResultFaultException("0_00040");
		}
		 
		//格式化JSON
		JSONObject params = new JSONObject();  
	    params = params.fromObject(jsonData);
	    if(!params.getJSONObject("data").has("uid")) {
	    	throw new ResultFaultException("0_00041");
	    }else {
	    	String uid= params.getJSONObject("data").getString("uid");
	 	    if(uid==null) {
	 	    	throw new ResultFaultException("0_00041");
	 	    }else {
	 	    	loginName=uid;
	 	    }
	    }
	   
		String ip = request.getHeader("x-forwarded-for"); 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("Proxy-Client-IP"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("WL-Proxy-Client-IP"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("HTTP_CLIENT_IP"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
	    } 
	    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
	      ip = request.getRemoteAddr(); 
	    } 
		if(StringUtils.isNotBlank(loginName)){
			UserBean userBean=new UserBean();
			userBean.setUserName(loginName);
			Integer userId=userService.getUserByUserBean(userBean);
			if(userId!=null){
				UserEmployeeBean userEmployee=userService.getUserEmployee(userId,ip);
				request.getSession().setMaxInactiveInterval(Math.round(AppConstant.SESSION_TIMEOUT));
				request.getSession().setAttribute(AppConstant.SESSIONUSER,userEmployee);
				return ResultMap.success(userEmployee);
			}else {
				throw new ResultFaultException("1_00002");
			}
		}
		throw new ResultFaultException("0_00001");
	}
}
